package com.empire.framework.common.util.crypto;


import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;

import java.nio.charset.StandardCharsets;
import java.security.Security;

/**
 * SM3加密工具类（基于BouncyCastle实现）
 * SM3是国家密码管理局发布的密码杂凑算法标准，适用于数字签名和验证等场景
 */
public class Sm3Util {

    static {
        // 注册BouncyCastle加密服务提供者
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 计算字符串的SM3哈希值（十六进制字符串）
     * @param data 待加密的字符串
     * @return 32字节的SM3哈希值（转为64位十六进制字符串）
     */
    public static String sm3(String data) {
        if (data == null || data.isEmpty()) {
            throw new IllegalArgumentException("SM3加密数据不能为空");
        }
        // 将字符串转为字节数组（使用UTF-8编码）
        byte[] input = data.getBytes(StandardCharsets.UTF_8);
        // 计算SM3哈希
        byte[] hash = sm3(input);
        // 将字节数组转为十六进制字符串
        return Hex.toHexString(hash).toLowerCase();
    }

    /**
     * 计算字节数组的SM3哈希值
     * @param data 待加密的字节数组
     * @return 32字节的SM3哈希值
     */
    public static byte[] sm3(byte[] data) {
        if (data == null || data.length == 0) {
            throw new IllegalArgumentException("SM3加密数据不能为空");
        }
        // 初始化SM3摘要算法
        SM3Digest digest = new SM3Digest();
        // 输入数据
        digest.update(data, 0, data.length);
        // 计算哈希值
        byte[] result = new byte[digest.getDigestSize()];
        digest.doFinal(result, 0);
        return result;
    }

    /**
     * 计算HMac-SM3哈希值（带密钥的SM3）
     * @param data 待加密的字符串
     * @param key 密钥字符串
     * @return 32字节的HMac-SM3哈希值（转为64位十六进制字符串）
     */
    public static String hmacSm3(String data, String key) {
        if (data == null || data.isEmpty()) {
            throw new IllegalArgumentException("HMac-SM3加密数据不能为空");
        }
        if (key == null || key.isEmpty()) {
            throw new IllegalArgumentException("HMac-SM3密钥不能为空");
        }
        // 转换为字节数组
        byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
        byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
        // 计算HMac-SM3
        HMac hmac = new HMac(new SM3Digest());
        hmac.init(new KeyParameter(keyBytes));
        hmac.update(dataBytes, 0, dataBytes.length);
        byte[] result = new byte[hmac.getMacSize()];
        hmac.doFinal(result, 0);
        // 转为十六进制字符串
        return Hex.toHexString(result).toLowerCase();
    }

    /**
     * 验证SM3哈希值是否匹配
     * @param data 原始数据
     * @param expectedHash 预期的SM3哈希值（十六进制字符串）
     * @return 匹配返回true，否则返回false
     */
    public static boolean verify(String data, String expectedHash) {
        if (expectedHash == null || expectedHash.isEmpty()) {
            return false;
        }
        // 计算原始数据的哈希值
        String actualHash = sm3(data);
        // 比较两个哈希值（忽略大小写）
        return actualHash.equalsIgnoreCase(expectedHash);
    }
}

